using System.IO;

namespace RollManager.Library.Utils
{
    public partial class DirectoryHelper
    {
        private const string FILTER_ALL_FILES = "*";

        private readonly ProgressReporter output;

        public DirectoryHelper( ProgressReporter output )
        {
            this.output = output;
        }

        public void Copy( string srcDir, string destDir )
        {
            Copy( srcDir, destDir, FILTER_ALL_FILES, true );
        }

        public void Copy( string srcDir, string destDir, bool recursive )
        {
            Copy( srcDir, destDir, FILTER_ALL_FILES, recursive );
        }

        public void Copy( string srcDir, string destDir, string filter )
        {
            Copy( srcDir, destDir, filter, true );
        }

        public void Copy( string srcDir, string destDir, string filter, bool recursive )
        {
            DirectoryInfo srcPath = new DirectoryInfo( srcDir );
            DirectoryInfo targetPath = new DirectoryInfo( destDir );

            if( string.IsNullOrEmpty( filter ) )
            {
                filter = FILTER_ALL_FILES;
            }

            CopyDirectory( srcPath, targetPath, filter, recursive );
        }

        private void CopyDirectory( DirectoryInfo srcPath, DirectoryInfo targetPath, string filter, bool recursive )
        {
            // If the target folder does not exist then create it.
            if( !targetPath.Exists )
            {
                LogFormat( "Creating directory {0}", targetPath.FullName );
                MethodRepeater.RepeatMethod( delegate { targetPath.Create(); }, output, 5 );
            }

            // Copy files first
            foreach( FileInfo fileInfo in srcPath.GetFiles( filter ) )
            {
                string destFile = Path.Combine( targetPath.FullName, fileInfo.Name );

                LogFormat( "Copying file {0} to {1}", fileInfo.FullName, destFile );

                // remove readonly permissions if they are present.
                FileInfo destFileInfo = new FileInfo( destFile );
                if( destFileInfo.Exists && destFileInfo.IsReadOnly )
                {
                    destFileInfo.Attributes = FileAttributes.Normal;
                }

                MethodRepeater.RepeatMethod( delegate { fileInfo.CopyTo( destFile, true ); }, output, 5 );
            }

            if( recursive )
            {
                // Copy sub-folder 
                foreach( DirectoryInfo dirInfo in srcPath.GetDirectories() )
                {
                    CopyDirectory( dirInfo, new DirectoryInfo( Path.Combine( targetPath.FullName, dirInfo.Name ) ), filter, recursive );
                }
            }
        }

        private void LogFormat( string str, params object[] args )
        {
            output.Add( string.Format( str, args ) );
        }
    }
}